package com.ztesoft.book.api.controller.base;

import com.github.pagehelper.PageInfo;
import com.ztesoft.book.common.constant.Constant;
import com.ztesoft.book.common.utils.Result;
import com.ztesoft.book.common.utils.exception.ServiceException;
import com.ztesoft.book.core.base.base.dto.BaseEntity;
import com.ztesoft.book.core.base.base.service.BaseExService;
import com.ztesoft.book.core.sys.sysuser.dto.SysUserDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description Controller公共组件
 * @Author YangFan
 * @Date 2021-06-15 15:46
 */
@Slf4j
public abstract class BaseController<S extends BaseExService, T extends BaseEntity> {


    /**
     * 方法功能描述:
     * < 获取Service >
     *
     * @return S                            【返回值 注释说明】
     *
     * @author YangFan
     * @date 2021-06-30 08:02
     */
    protected abstract S getService();


    protected SysUserDTO getShiroUser() {
        return getService().getShiroUser();
    }


    @PostMapping("/findById")
    public @ResponseBody
    Result findById(@RequestBody String id) {
        try {
            T t = (T) getService().findById(id);
            return Result.success(t);
        }
        catch (Exception ex) {
            log.error(ex.getMessage());
            return Result.error("获取失败！");
        }
    }


    @PostMapping("/findOne")
    public @ResponseBody
    Result findOne(@RequestBody T dto) {
        try {
            handleBeforeFindOne(dto);
            T t = (T) getService().findOne(dto);
            return Result.success(t);
        }
        catch (Exception ex) {
            log.error(ex.getMessage());
            return Result.error("获取失败！");
        }
    }


    @PostMapping("/findList")
    public @ResponseBody
    Result findList(@RequestBody T dto) {
        try {
            handleBeforeFindList(dto);
            List<T> list = getService().findList(dto);
            return Result.success(list);
        }
        catch (Exception ex) {
            log.error(ex.getMessage());
            return Result.error("获取失败！");
        }
    }


    @PostMapping("/findPage")
    public @ResponseBody
    Result findPage(@RequestBody T dto) {
        try {
            if (dto.getCurrent() == null || dto.getPageSize() == null) {
                throw new ServiceException("分页参数不能为空");
            }
            int integerCurrent = dto.getCurrent();
            int integerPageSize = dto.getPageSize();

            handleBeforeFindPage(dto);
            PageInfo<T> pageInfo = getService().findPage(dto, integerCurrent, integerPageSize);
            Map<String, Object> rtnMap = new HashMap<>(16);
            rtnMap.put("pageSize", pageInfo.getPageSize());
            rtnMap.put("total", pageInfo.getTotal());
            rtnMap.put("pages", pageInfo.getPages());
            rtnMap.put("current", pageInfo.getPageNum());
            rtnMap.put("list", pageInfo.getList());

            return Result.success(rtnMap);
        }
        catch (NumberFormatException numberFormatException) {
            return Result.error("参数不合法！");
        }
        catch (Exception e) {
            log.error("查询失败", e);
            return Result.error(e.getMessage());
        }
    }


    @PostMapping("/saveObject")
    public @ResponseBody
    Result saveObject(@RequestBody T t) {
        try {
            handleBeforeSaveObject(t);
            getService().saveObject(t);
            return Result.success(t);
        }
        catch (ServiceException ex) {
            return Result.error(ex.getMessage());
        }
        catch (Exception ex) {
            log.error(ex.getMessage());
            return Result.error("新增失败！");
        }
    }


    @PostMapping("/updateObject")
    public @ResponseBody
    Result updateObject(@RequestBody T t) {
        try {
            if (t.getId() == null) {
                throw new ServiceException("ID不能为空");
            }
            handleBeforeUpdateObject(t);
            getService().updateObject(t);
            return Result.success("修改成功！");
        }
        catch (ServiceException ex) {
            return Result.error(ex.getMessage());
        }
        catch (Exception ex) {
            log.error(ex.getMessage());
            return Result.error("修改失败！");
        }
    }


    @PostMapping("/deleteObject")
    public @ResponseBody
    Result deleteObject(@RequestBody String id) {
        try {
            if (StringUtils.isBlank(id)) {
                throw new ServiceException("ID不能为空");
            }
            handleBeforeDeleteObject(id);
            getService().deleteObject(id);
            return Result.success("删除成功！");
        }
        catch (ServiceException ex) {
            return Result.error(ex.getMessage());
        }
        catch (Exception ex) {
            log.error(ex.getMessage());
            return Result.error("删除失败！");
        }
    }


    /**
     * 方法功能描述:
     * < 根据ID删除对象（逻辑删除） >
     *
     * @param id 【参数 1 注释说明】
     *
     * @return Result                        【返回值 注释说明】
     *
     * @author YangFan
     * @date 2021-06-30 07:33
     */
    @PostMapping("/fakeDelete")
    public @ResponseBody
    Result fakeDelete(@RequestBody String id) {
        try {
            if (StringUtils.isBlank(id)) {
                throw new ServiceException("ID不能为空");
            }
            handleBeforeDeleteObject(id);
            getService().fakeDeleteByPrimaryKey(id);
            return Result.success("删除成功！");
        }
        catch (ServiceException ex) {
            return Result.error(ex.getMessage());
        }
        catch (Exception ex) {
            log.error(ex.getMessage());
            return Result.error("删除失败！");
        }
    }

    /**
     * 获取登录用户的学号或者是openid
     *
     * @param httpServletRequest
     *
     * @return 学号或者是openid
     */
    protected String getUserSnoOrOpenid(HttpServletRequest httpServletRequest) {

        return (String) httpServletRequest.getAttribute(Constant.SNOOROPENID);
    }

    protected void handleBeforeFindOne(T t) {
        // 查找单条前方法
    }

    protected void handleBeforeFindList(T t) {
        // 查找列表前方法
    }

    protected void handleBeforeFindPage(T t) {
        // 查找分页列表前方法
    }

    protected void handleBeforeSaveObject(T t) {
        // 新增前方法
    }

    protected void handleBeforeUpdateObject(T t) {
        // 修改前方法
    }

    protected void handleBeforeDeleteObject(String id) {
        // 删除前方法
    }

}
